#ifndef _SNIFFING_H_
#define _SNIFFING_H_

#include "include.h"

// Taille de capture par paquet
#define SNAP_LEN 1518

// Taille du header ethernet (14 bytes)
#define SIZE_ETHERNET 14

// Header Ethernet
struct sniff_ethernet
{
	u_char  ether_dhost[ETHER_ADDR_LEN];  // Destination
	u_char  ether_shost[ETHER_ADDR_LEN];  // Source
	u_short ether_type;                   // IP ? ARP ? RARP ? etc.
};

// Header IP
struct sniff_ip
{
	u_char  ip_vhl;  // Version << 4 | Taille du header >> 2
	u_char  ip_tos;  // Type de service
	u_short ip_len;  // Taille totale
	u_short ip_id;   // Identification
	u_short ip_off;  // Taille de l'offset de fragmentation
	
	// Flags et masque pour la fragmentation
	#define IP_RF 0x8000
	#define IP_DF 0x4000
	#define IP_MF 0x2000
	#define IP_OFFMASK 0x1fff
	
	u_char ip_ttl;  // Time to live
	u_char ip_p;    // Protocole
	u_short ip_sum;  // Checksum

	struct in_addr ip_src;  // Adresse source
	struct in_addr ip_dst; 	// Adresse destination
};

#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)  (((ip)->ip_vhl) >> 4)

// Header IPv6
struct sniff_ipv6
{
	u_int8_t version:4,
	         traffic_class_high:4;
	u_int8_t traffic_class_low:4,
	         flow_label_high:4;
	
	u_int16_t flow_label_low;
	u_int16_t payload_length;
	u_int8_t  next_header;
	u_int8_t  hop_limit;
	
	u_char src_addr[16];
	u_char dst_addr[16];
};

// Header TCP
typedef u_int tcp_seq;

struct sniff_tcp
{
	u_short th_sport;  // Port source
	u_short th_dport;  // Port destination
	tcp_seq th_seq;    // Numéro de séquence
	tcp_seq th_ack;    // Numéro d'acquittement
	u_char  th_offx2;  // Offset des données, rsvd
	#define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)
	u_char  th_flags;
	#define TH_FIN  0x01
	#define TH_SYN  0x02
	#define TH_RST  0x04
	#define TH_PUSH 0x08
	#define TH_ACK  0x10
	#define TH_URG  0x20
	#define TH_ECE  0x40
	#define TH_CWR  0x80
	#define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
	u_short th_win;  // Fenêtre
	u_short th_sum;  // Checksum
	u_short th_urp;  // Urgent
};

// Header UDP

struct sniff_udp
{
	u_short uh_sport;
	u_short uh_dport;
	u_short uh_len;
	u_short uh_sum;
};

// Fonction de callback lorsqu'un paquet est capturé
void got_packet(u_char* args, const struct pcap_pkthdr* header, const u_char* packet, struct timeval* time_begin_capture);

// Fonction d'affichage
void print_time(time_t tv_sec, time_t tv_usec);
void print_eth_type(u_short eth_type);
void print_ipv6_next_header(u_int8_t next_header);
void print_ipv4_protocol(u_char proto);
void print_ipv4_service(u_short port, char* type);

#endif
